package bot.module.th.estimation;

import game.gamestorage.texas.db.estimation.GetterDBProjector;
import game.gamestorage.texas.db.estimation.GetterQueryExecution;
import util.DebugOut;
import bot.module.equity.SubjectiveAllinEquity;
import bot.module.th.shc.TableBSS;

/**
 * Estimation of one opponent at one competition
 * - BY NOW ONLY THE ESTIMATION OF THE SPECIAL ROUND "PREFLOPSHC" IS EXEMPLARILY IMPLEMENTED -
 * 
 * @author Witthold/Korol
 */
//@SuppressWarnings("unused")
public class Opponent {

	private int playerId;
	private String playerName;
	private int competitionId;
	private int lastEvaledHandId;

	private IF_EstimationAtRound[] estimationAtRounds;

	private GetterDBProjector gDBP;

	/**
	 * Behaviour of opponent<br>
	 * D0: 0-4 rounds<br>
	 * D1.0: looseness, 0-100<br>
	 * D1.1: aggression, 0-100<br>
	 * D1.2: bluffing statistic (bluffed x of y hands)
	 */
	private int[][] behaviourAtRounds = new int[4][3];
	/** overall stats */ 
	private int[][] actionsAtRounds = new int[4][4];
	private int[] numPlayedAtRounds = new int[4]; // TODO not implemented yet
	/** average through all rounds -> one complete competition */
	private int[] behaviourAtCompetition = new int[3];	// TODO not implemented yet


	public int[][] getBehaviourAtRounds(){
		return behaviourAtRounds;
	}
	
	/**
	 * Constructor by opponents id and competition_id
	 * 	
	 * @param player_id - already generated by db
	 * @param competition_id - already generated by db
	 */
	public Opponent(int player_id, int competition_id) {

		this.playerId = player_id;
		this.competitionId = competition_id;
		this.lastEvaledHandId = 0;
		
		gDBP = new GetterDBProjector(playerId, competitionId, lastEvaledHandId);

		/* no need for - sets only for opponents playerName from DB */
		gDBP.setCompetitionPlayers();
		playerName = gDBP.getCompetitonPlayers().get(player_id);
		DebugOut.showVerboseEstimation("Opponent: " + playerName + " at " + competitionId);

		init();

	}


	/**
	 * instanciate estimations at rounds
	 */
	private void init() {		
		
		estimationAtRounds = new IF_EstimationAtRound[5];

		estimationAtRounds[0] = new PreFlopShc(new TableBSS());
		estimationAtRounds[1] = new PreFlop();
		estimationAtRounds[2] = new Flop();
		estimationAtRounds[3] = new Turn();
		estimationAtRounds[4] = new River();

	}

	
	/**
	 * estimate opponent over all rounds</br>
	 * TODO better as boolean like at IF_Estimation 
	 */
	public void estimate() {		

		//gDBP = new GetterDBProjector(); // already instanciated in declaration
		
		DebugOut.showVerboseEstimation("Opponent: " + playerName + " at " + competitionId);
		
		for (int i = 0; i < estimationAtRounds.length; i++) {
			// DebugOut.showVerboseEstimation("Opponent.estimate round: " + i);
			estimationAtRounds[i].fetchData(gDBP);
			estimationAtRounds[i].estimate();
			estimationAtRounds[i].mergeIntoRound();
			estimationAtRounds[i].mergeIntoOverall(this);
		}
		
		/* remember lastEvaledHandId, has to be last HandId at this time */
		int latestHandId = GetterQueryExecution.getLatestHandId();
		lastEvaledHandId = latestHandId;
		gDBP.upateLastEvaledHandId(lastEvaledHandId);
	}


	/**
	 * estimation over all rounds of a hand
	 * 
	 * @param round 0-4
	 * @param category - characteristics given by the estimations at rounds
	 */
	protected void setBehaviourAtRound(int round, int[] category) { // TODO not implemented yet

		for (int i = 0; i < category.length; i++) {
			behaviourAtRounds[round][i] = category[i];
		}

	}


	/**
	 * estimation over all hands of a competition
	 */
	private void setBehaviourAtCompetition() {	// TODO not implemented yet

		behaviourAtCompetition = new int[] {42,42,42};
	}


	/*
	 * Getters
	 */

	/**
	 * @return the estimationAtRounds
	 */
	public IF_EstimationAtRound[] getEstimationAtRounds() {
		return estimationAtRounds;
	}


	public void setActionAtRound(int round, int[] actions) {
		
		for (int i = 0; i < actions.length; i++) {
			actionsAtRounds[round][i] = actions[i];
		}
		
	}
	
	public String getPlayerName() {
		return playerName;
	}

}
